package service;

import common.Message;
import common.MessageType;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author 余一
 * @date 2021/10/30  11:58
 * 服务端和客户端保持通信的线程
 */
public class ServerClientThread extends Thread{
    private Socket socket;
    private String userId;
    //用户存储离线消息的集合容器
    private static ArrayList<Message> messageArrayList = new ArrayList<>();
    //用户存储离线文件消息的集合容器
    private static ArrayList<Message> filesArrayList = new ArrayList<>();

    ServerClientThread(String userId,Socket socket){
        this.socket = socket;
        this.userId = userId;
    }

    @Override
    public void run() {
        while (true) {
            try {
                //通信时，服务端会不断的接收客户端传递的消息数据
                System.out.println("【服务端】和客户端【" + userId + "】在保持着通信...");
                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                Message message = (Message) objectInputStream.readObject();//没有读到数据对象时，线程会阻塞
                if (message.getMesType().equals(MessageType.MESSAGE_GET_ONLINE_USER)) {
                    //客户端请求在线用户列表
                    System.out.println("用户【"+userId+"】请求在线用户列表");
                    String onlineUser = ThreadManager.getOnlineUser();
                    //将用户列表信息封装到message中
                    Message message1 = new Message();
                    message1.setMesType(MessageType.MESSAGE_RET_ONLINE_USER);
                    message1.setContent(onlineUser);
                    message1.setGetter(userId);
                    //将message发送给对应客户端
                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                    objectOutputStream.writeObject(message1);

                }else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)){
                    String receiver = message.getGetter();
                    //判断接收消息的用户是否存在
                    if (QQServer.checkUser(receiver)){
                        //如果存在，再判断接收消息的用户是否离线
                        if (!ThreadManager.ifOnline(receiver)) {
                            //在线，直接发给接收者
                            OutputStream outputStream = ThreadManager.getThread(receiver).getSocket().getOutputStream();
                            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                            System.out.println("用户【"+message.getSender()+"】向【" +receiver+ "】说："+message.getContent());
                            objectOutputStream.writeObject(message);
                        }else {
                            //不在线，保存离线消息到服务端
                            //先判断集合是否为空
                            if (messageArrayList.isEmpty()) {
                                //为空可以直接添加message
                                messageArrayList.add(message);
                            }else {
                                //不为空，要判断接收离线消息的用户是否为同一个
                                if (message.getGetter().equals(messageArrayList.get(0).getGetter())) {
                                    //是同一个，就直接添加message到集合中
                                    messageArrayList.add(message);
                                } else {
                                    //不是同一个，需要重新创建一个容器，将message添加到该容器中
                                    messageArrayList = new ArrayList<>();
                                    messageArrayList.add(message);
                                }
                            }
                            System.out.println("用户【"+message.getSender()+"】向离线用户【" +receiver+ "】留言："+message.getContent());
                            OfflineMessageThreadManager.addOfflineMessage(receiver,messageArrayList);
                        }
                    }else {
                        //用户不存在
                        message.setContent("用户【"+ receiver +"】不存在，无法留言");
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
                        LocalDateTime now = LocalDateTime.now();
                        String nowDate = formatter.format(now);
                        message.setSendTime(nowDate);

                        System.out.println("用户【" + receiver + "】不存在");
                        OutputStream outputStream = ThreadManager.getThread(message.getSender()).getSocket().getOutputStream();
                        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                        message.setSender("服务端");
                        objectOutputStream.writeObject(message);
                    }

                }else if (message.getMesType().equals(MessageType.MESSAGE_TO_ALL)){
                    HashMap<String, ServerClientThread> threadHashMap =
                            ThreadManager.getThreadHashMap();
                    //遍历集合，向除发送者以外的其他人群发消息
                    threadHashMap.forEach((onlineUserId,serverClientThread) -> {
                        if (!onlineUserId.equals(message.getSender())){
                            try {
                                OutputStream outputStream = serverClientThread.getSocket().getOutputStream();
                                ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                                System.out.println("用户【"+ message.getSender() + "】向所有在线用户说：" +message.getContent());
                                objectOutputStream.writeObject(message);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)){
                    String receiver = message.getGetter();
                    //判断接收消息的用户是否存在
                    if (QQServer.checkUser(receiver)){
                        //如果存在，再判断接收消息的用户是否离线
                        if (!ThreadManager.ifOnline(receiver)) {
                            //在线，直接发给接收者
                            OutputStream outputStream = ThreadManager.getThread(message.getGetter()).getSocket().getOutputStream();
                            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                            //提示信息
                            System.out.println("\n【" + message.getSender() + "】给【" + message.getGetter() + "】发送文件：" + message.getSrc() + "到对方目录：" + message.getTarget());
                            objectOutputStream.writeObject(message);
                        }else {
                            //不在线，保存离线消息到服务端
                            //先判断文件集合是否为空
                            if (filesArrayList.isEmpty()) {
                                //为空可以直接添加message
                                filesArrayList.add(message);
                            }else {
                                //不为空，要判断接收离线消息的用户是否为同一个
                                if (message.getGetter().equals(filesArrayList.get(0).getGetter())) {
                                    //是同一个，就直接添加message到集合中
                                    filesArrayList.add(message);
                                } else {
                                    //不是同一个，需要重新创建一个容器，将message添加到该容器中
                                    filesArrayList = new ArrayList<>();
                                    filesArrayList.add(message);
                                }
                            }
                            System.out.println("用户【"+message.getSender()+"】向离线用户【" +receiver+ "】传送文件："+message.getSrc());
                            OfflineFilesThreadManager.addOfflineMessage(receiver,filesArrayList);
                        }
                    }else {
                        //用户不存在
                        message.setContent("用户【"+ receiver +"】不存在，文件传输失败");
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
                        LocalDateTime now = LocalDateTime.now();
                        String nowDate = formatter.format(now);
                        message.setSendTime(nowDate);

                        System.out.println("用户【" + receiver + "】不存在");
                        OutputStream outputStream = ThreadManager.getThread(message.getSender()).getSocket().getOutputStream();
                        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                        message.setSender("服务端");
                        objectOutputStream.writeObject(message);
                    }

                }else if (message.getMesType().equals(MessageType.MESSAGE_CLIENT_EXIT)){
                    System.out.println(userId + "退出...");
                    ThreadManager.removeUser(userId);
                    socket.close();
                    break;
                }else {
                    System.out.println("其他message暂时不做处理...");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public Socket getSocket() {
        return socket;
    }
}
